package maMetrics;

import java.util.Iterator;

import com.telelogic.rhapsody.core.IRPAttribute;
import com.telelogic.rhapsody.core.IRPClass;
import com.telelogic.rhapsody.core.IRPInterfaceItem;
import com.telelogic.rhapsody.core.IRPOperation;
import com.telelogic.rhapsody.core.IRPPackage;
import com.telelogic.rhapsody.core.IRPProject;

import maConfigration.MetricSettings;
import maUtil.LogFile;
import maUtil.RecordUnit;
import maUtil.SortedRecords;

public class MetricCPD extends MetricObject{
	
	SortedRecords _srPkg = null;
	SortedRecords _srCls = null;
	SortedRecords _srOp = null;
	
	LogFile _logFile = null;
	LogFile _logFileProj = null;
	LogFile _logFileCsv = null;
	
	int _nSum;
	//number of packages/classes/operations in total
	float _nSumPkg;
	float _nSumCls;
	float _nSumOp;
	//number of packages/classes/operations that is commented c == commented
	float _cPkg;
	float _cCls;
	float _cOp;
	
	//percentage per project
	float _nSumProjPkg;
	float _nSumProjCls;
	float _nSumProjOp;
	//number of packages/classes/operations that is commented c == commented for each project
	float _cProjPkg;
	float _cProjCls;
	float _cProjOp;
	
	
	
	public MetricCPD(MetricSettings ms)
	{
		super(ms);
		
		_sMetricName = "Metric: Comment Percentage Description";
		if(_isApplyToPkg)
		{
			_srPkg = new SortedRecords(2000, _sMetricName + " for packages in exported interfaces");
		}
		if(_isApplyToCls)
		{
			_srCls = new SortedRecords(2000, _sMetricName + " for classes");
		}
		if(_isApplyToOp)
		{
			_srOp = new SortedRecords(2000, _sMetricName + " for operations/methods");
		}
		
		_logFile = new LogFile("MetricCPDForSystem.txt");
		_logFileProj = new LogFile("MetricCPDSortedPerProject.txt");
		_logFileCsv = new LogFile("MetricCPD.csv");
		
		_nSum = 0;
		
		_nSumPkg = 0;
		_nSumCls = 0;
		_nSumOp = 0;
		_cPkg = 0;
		_cCls = 0;
		_cOp = 0;
		
		_nSumProjPkg = 0;
		_nSumProjCls = 0;
		_nSumProjOp = 0;
		_cProjPkg = 0;
		_cProjCls = 0;
		_cProjOp = 0;
		
	}
	
	private void getPkgs(IRPPackage pkg){
		Iterator pkgs = pkg.getPackages().toList().iterator();
		while(pkgs.hasNext())
		{
			IRPPackage pkgStep = (IRPPackage) pkgs.next();
			Iterator pkgsToBeMeasured = pkgStep.getPackages().toList().iterator();
			while(pkgsToBeMeasured.hasNext())
			{
				IRPPackage pkgToGetDesc = (IRPPackage)pkgsToBeMeasured.next();
				getDesc(pkgToGetDesc);
			}
		}
	}
	
	private void getDesc(IRPPackage pkg){
		_nSumPkg += 1;
		_nSumProjPkg += 1;
		int tmp = pkg.getDescription().length();
		if(pkg.getDescription().length() > 5)
		{
			_cPkg += 1;
			_cProjPkg += 1;
		}
		else
		{
			_srPkg.add(new RecordUnit(0, pkg.getFullPathNameIn() + " in project: " + pkg.getProject().getName()));
		}
	}
	
	private void getDesc(IRPClass cls){
		_nSumCls += 1;
		_nSumProjCls += 1;
		if(cls.getDescription().length() > 5)
		{
			_cCls += 1;
			_cProjCls += 1;
		}
		else
		{
			_srCls.add(new RecordUnit(0, cls.getFullPathNameIn() + " in project: " + cls.getProject().getName()));
		}
	}
	
	private void getDesc(IRPOperation op){
		_nSumOp += 1;
		_nSumProjOp += 1;
		if(op.getDescription().length() > 5)
		{
			_cOp += 1;
			_cProjOp += 1;
		}
		else
		{
			_srOp.add(new RecordUnit(0, op.getFullPathNameIn() + " in project: " + op.getProject().getName()));
		}
	}
	

	@Override
	public void finish() {
		// TODO Auto-generated method stub
		_logFile.logLn("System comment percentage");
		try{
			float p = 100 * _cPkg/_nSumPkg;
			float c = 100 * _cCls/_nSumCls;
			float  o = 100 * _cOp/_nSumOp;
			_logFile.logLn(p + "% of the ExportedInterfacesPkg are commented");
			_logFile.logLn(c + "% of the classes are commented");
			_logFile.logLn(o + "% of the methods are commented");
			
			//logging csv file for report
			_logFileCsv.logLn("Value,Part");
			_logFileCsv.logLn(p + ",ExportedInterfacesPkg");
			_logFileCsv.logLn(c + ",classes");
			_logFileCsv.logLn(o + ",methods");
		}
		catch(Exception e){
			System.out.println("Something went wrong somewhere: \n" + e.getMessage());
		}
			
		
	}

	@Override
	public int applyInProj(IRPProject proj) {
		// TODO Auto-generated method stub
		if(!_isApplyToProj)
			return 0;
		
		_logFileProj.logLn("Comment Percentage for " +proj.getName()+ " and names of maximum 2000 each of those that is not commented");
		if(_nSumProjPkg > 0)
			_logFileProj.logLn(((_cProjPkg/_nSumProjPkg) * 100) + "% of the packages under ExportedInterfacesPkg in "+proj.getName()+" are commented");
		else
			_logFileProj.logLn("There is no ExportedInterfacePkg or packages under ExportedInterfacePkg");
		if(_nSumProjCls > 0)
			_logFileProj.logLn(((_cProjCls/_nSumProjCls) * 100) + "% of the classes in "+proj.getName()+" are commented");
		else
			_logFileProj.logLn("There exists no classes in this project");
		if(_nSumProjOp > 0)
			_logFileProj.log(((_cProjOp/_nSumProjOp) * 100) + "% of the methods in "+proj.getName()+" are commented");
		else
			_logFileProj.log("There exists no methods in this project");	
			
		_logFileProj.logLn("Uncommented packages (ExportedInterfacePkg)/classes/methods");
		_logFileProj.log(_srPkg.getAllString());
		_logFileProj.log(_srCls.getAllString());
		_logFileProj.log(_srOp.getAllString());
		
		_srPkg = new SortedRecords(2000, _sMetricName + " for packages in exported interfaces");
		_srCls = new SortedRecords(2000, _sMetricName + " for classes");
		_srOp = new SortedRecords(2000, _sMetricName + " for operations/methods");
		
		_cProjPkg = 0;
		_cProjCls = 0;
		_cProjOp = 0;
		_nSumProjPkg = 0;
		_nSumProjCls = 0;
		_nSumProjOp = 0;
		
		int n = _nSum;
		_nSum = 0;
		
		return n;
	}

	@Override
	public int applyInPkg(IRPPackage pkg) {
		// TODO Auto-generated method stub
		if(!_isApplyToPkg)
			return 0;
		String test = pkg.getName();
		if(test.equals("ExportedInterfacesPkg"))
		{
			getPkgs(pkg);
		}
		return 0;
	}

	@Override
	public int applyInCls(IRPClass cls) {
		// TODO Auto-generated method stub
		if(!_isApplyToCls)
			return 0;
		getDesc(cls);
		return 0;
	}

	@Override
	public int applyInItf(IRPInterfaceItem itf) {
		// TODO Auto-generated method stub
		return 0;
	}

	@Override
	public int applyInOp(IRPOperation op) {
		// TODO Auto-generated method stub
		if(!_isApplyToOp)
			return 0;
		getDesc(op);
		return 0;
	}

	@Override
	public int applyInAttr(IRPAttribute attrb) {
		// TODO Auto-generated method stub
		return 0;
	}


}
